<!--
  网络功能演示页面
  
  展示Electron中各种网络功能：
  - HTTP/HTTPS请求
  - WebSocket通信
  - 文件下载管理
  - 网络状态监控
  - 代理设置
  - Cookie管理
-->

<template>
  <div class="network-features-page">
    <!-- 页面标题 -->
    <div class="header">
      <h2>🌐 网络功能演示</h2>
      <p class="subtitle">展示 Electron 中各种网络通信功能</p>
    </div>

    <!-- 功能分组 -->
    <div class="demo-sections">
      
      <!-- 1. HTTP/HTTPS 请求 -->
      <div class="demo-section">
        <h3>🌍 HTTP/HTTPS 请求</h3>
        <p class="description">演示各种HTTP方法和请求配置</p>
        <div class="controls">
          <div class="request-form">
            <div class="form-row">
              <select v-model="httpRequest.method" class="method-select">
                <option value="GET">GET</option>
                <option value="POST">POST</option>
                <option value="PUT">PUT</option>
                <option value="DELETE">DELETE</option>
                <option value="PATCH">PATCH</option>
              </select>
              <input 
                v-model="httpRequest.url" 
                placeholder="请求URL (如: https://api.github.com/users/github)"
                class="url-input"
              >
              <button @click="sendHttpRequest" class="btn btn-primary" :disabled="httpRequest.loading">
                {{ httpRequest.loading ? '请求中...' : '发送请求' }}
              </button>
            </div>
            
            <div class="form-row">
              <textarea 
                v-model="httpRequest.headers" 
                placeholder="请求头 (JSON格式): { &quot;Content-Type&quot;: &quot;application/json&quot; }"
                class="headers-input"
              ></textarea>
            </div>
            
            <div class="form-row" v-if="httpRequest.method !== 'GET'">
              <textarea 
                v-model="httpRequest.body" 
                placeholder="请求体 (JSON格式)"
                class="body-input"
              ></textarea>
            </div>
          </div>
        </div>

        <div class="request-history">
          <h4>请求历史：</h4>
          <div v-if="httpHistory.length === 0" class="empty-state">
            暂无请求记录
          </div>
          <div v-else class="history-list">
            <div v-for="(request, index) in httpHistory" :key="index" class="history-item">
              <div class="request-header">
                <span :class="['method-badge', request.method.toLowerCase()]">{{ request.method }}</span>
                <span class="url">{{ request.url }}</span>
                <span :class="['status-badge', getStatusClass(request.status)]">{{ request.status }}</span>
                <span class="timestamp">{{ request.timestamp }}</span>
              </div>
              <div class="request-details" v-if="request.expanded">
                <div class="response-info">
                  <h5>响应信息：</h5>
                  <p>状态: {{ request.status }} {{ request.statusText }}</p>
                  <p>响应时间: {{ request.responseTime }}ms</p>
                  <p>内容长度: {{ request.contentLength }}</p>
                </div>
                <div class="response-headers" v-if="request.responseHeaders">
                  <h5>响应头：</h5>
                  <pre class="headers-display">{{ JSON.stringify(request.responseHeaders, null, 2) }}</pre>
                </div>
                <div class="response-body">
                  <h5>响应体：</h5>
                  <pre class="response-display">{{ formatResponse(request.response) }}</pre>
                </div>
              </div>
              <button @click="toggleRequestDetails(index)" class="btn btn-sm btn-secondary">
                {{ request.expanded ? '收起详情' : '查看详情' }}
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 2. WebSocket 通信 -->
      <div class="demo-section">
        <h3>🔌 WebSocket 通信</h3>
        <p class="description">实时双向通信演示</p>
        <div class="controls">
          <div class="websocket-form">
            <div class="form-row">
              <input 
                v-model="websocket.url" 
                placeholder="WebSocket URL (如: wss://echo.websocket.org/)"
                class="ws-url-input"
                :disabled="websocket.connected"
              >
              <button 
                @click="websocket.connected ? disconnectWebSocket() : connectWebSocket()" 
                :class="['btn', websocket.connected ? 'btn-danger' : 'btn-primary']"
                :disabled="websocket.connecting"
              >
                {{ websocket.connecting ? '连接中...' : (websocket.connected ? '断开连接' : '连接') }}
              </button>
            </div>
            
            <div class="websocket-status">
              <div :class="['status-indicator', websocket.connected ? 'connected' : 'disconnected']">
                {{ websocket.connected ? '✅ 已连接' : '❌ 未连接' }}
              </div>
              <span v-if="websocket.connected" class="connection-info">
                连接时间: {{ formatTime(websocket.connectionTime) }}
              </span>
            </div>

            <div class="form-row" v-if="websocket.connected">
              <input 
                v-model="websocket.message" 
                placeholder="输入要发送的消息"
                class="message-input"
                @keyup.enter="sendWebSocketMessage"
              >
              <button @click="sendWebSocketMessage" class="btn btn-success" :disabled="!websocket.message.trim()">
                发送消息
              </button>
            </div>
          </div>
        </div>

        <div class="websocket-messages">
          <h4>消息记录：</h4>
          <div class="messages-container" ref="messagesContainer">
            <div v-if="websocketMessages.length === 0" class="empty-state">
              暂无消息记录
            </div>
            <div v-else>
              <div v-for="(msg, index) in websocketMessages" :key="index" :class="['message-item', msg.type]">
                <div class="message-header">
                  <span class="message-type">{{ msg.type === 'sent' ? '↗️ 发送' : '↙️ 接收' }}</span>
                  <span class="message-timestamp">{{ msg.timestamp }}</span>
                </div>
                <div class="message-content">{{ msg.content }}</div>
              </div>
            </div>
          </div>
          <div class="messages-actions" v-if="websocketMessages.length > 0">
            <button @click="clearWebSocketMessages" class="btn btn-secondary btn-sm">清空消息</button>
            <button @click="exportMessages" class="btn btn-success btn-sm">导出消息</button>
          </div>
        </div>
      </div>

      <!-- 3. 文件下载管理 -->
      <div class="demo-section">
        <h3>📥 文件下载管理</h3>
        <p class="description">文件下载和进度监控</p>
        <div class="controls">
          <div class="download-form">
            <div class="form-row">
              <input 
                v-model="download.url" 
                placeholder="下载URL (如: https://releases.ubuntu.com/20.04/ubuntu-20.04.6-desktop-amd64.iso)"
                class="download-url-input"
              >
              <input 
                v-model="download.filename" 
                placeholder="保存文件名 (可选)"
                class="filename-input"
              >
              <button @click="startDownload" class="btn btn-primary" :disabled="download.downloading">
                {{ download.downloading ? '下载中' : '开始下载' }}
              </button>
            </div>
          </div>
        </div>

        <div class="download-list">
          <h4>下载任务：</h4>
          <div v-if="downloadTasks.length === 0" class="empty-state">
            暂无下载任务
          </div>
          <div v-else>
            <div v-for="(task, index) in downloadTasks" :key="index" class="download-item">
              <div class="download-info">
                <div class="filename">{{ task.filename }}</div>
                <div class="download-stats">
                  <span>{{ formatFileSize(task.receivedBytes) }} / {{ formatFileSize(task.totalBytes) }}</span>
                  <span>{{ task.speed }}</span>
                  <span>{{ task.timeRemaining }}</span>
                </div>
              </div>
              <div class="download-progress">
                <div class="progress-bar">
                  <div class="progress-fill" :style="{ width: `${task.progress}%` }"></div>
                </div>
                <span class="progress-text">{{ task.progress }}%</span>
              </div>
              <div class="download-actions">
                <button 
                  v-if="task.status === 'downloading'" 
                  @click="pauseDownload(index)" 
                  class="btn btn-warning btn-sm"
                >
                  暂停
                </button>
                <button 
                  v-if="task.status === 'paused'" 
                  @click="resumeDownload(index)" 
                  class="btn btn-success btn-sm"
                >
                  继续
                </button>
                <button 
                  @click="cancelDownload(index)" 
                  class="btn btn-danger btn-sm"
                  :disabled="task.status === 'completed'"
                >
                  {{ task.status === 'completed' ? '已完成' : '取消' }}
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 4. 网络状态监控 -->
      <div class="demo-section">
        <h3>📊 网络状态监控</h3>
        <p class="description">实时监控网络连接状态和性能</p>
        <div class="controls">
          <button @click="refreshNetworkStatus" class="btn btn-primary">刷新网络状态</button>
          <button @click="runNetworkTest" class="btn btn-success" :disabled="networkTest.running">
            {{ networkTest.running ? '测试中...' : '网络性能测试' }}
          </button>
          <button @click="pingTest" class="btn btn-secondary">Ping 测试</button>
        </div>

        <div class="network-status-panel">
          <div class="status-grid">
            <div class="status-card">
              <h5>连接状态</h5>
              <div :class="['status-value', networkStatus.online ? 'online' : 'offline']">
                {{ networkStatus.online ? '🟢 在线' : '🔴 离线' }}
              </div>
              <p class="status-description">
                {{ networkStatus.online ? '网络连接正常' : '网络连接断开' }}
              </p>
            </div>

            <div class="status-card">
              <h5>连接类型</h5>
              <div class="status-value">{{ networkStatus.connectionType || '未知' }}</div>
              <p class="status-description">当前网络连接类型</p>
            </div>

            <div class="status-card">
              <h5>下载速度</h5>
              <div class="status-value">{{ networkStatus.downloadSpeed || '测试中' }}</div>
              <p class="status-description">估算下载速度</p>
            </div>

            <div class="status-card">
              <h5>延迟</h5>
              <div class="status-value">{{ networkStatus.latency || '测试中' }}</div>
              <p class="status-description">网络延迟时间</p>
            </div>
          </div>

          <div class="network-chart" v-if="networkChart.data.length > 0">
            <h5>网络性能图表</h5>
            <div class="chart-container">
              <canvas ref="networkCanvas" width="800" height="200"></canvas>
            </div>
          </div>
        </div>

        <div class="ping-results" v-if="pingResults.length > 0">
          <h4>Ping 测试结果：</h4>
          <div class="ping-list">
            <div v-for="(result, index) in pingResults" :key="index" class="ping-item">
              <span class="ping-host">{{ result.host }}</span>
              <span :class="['ping-time', result.success ? 'success' : 'failed']">
                {{ result.success ? `${result.time}ms` : '超时' }}
              </span>
              <span class="ping-timestamp">{{ result.timestamp }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 5. 代理设置 -->
      <div class="demo-section">
        <h3>🔧 代理设置</h3>
        <p class="description">配置和管理网络代理</p>
        <div class="controls">
          <div class="proxy-form">
            <div class="form-row">
              <select v-model="proxy.type" class="proxy-type-select">
                <option value="direct">直接连接</option>
                <option value="http">HTTP 代理</option>
                <option value="https">HTTPS 代理</option>
                <option value="socks4">SOCKS4 代理</option>
                <option value="socks5">SOCKS5 代理</option>
              </select>
              <input 
                v-model="proxy.host" 
                placeholder="代理主机"
                class="proxy-input"
                :disabled="proxy.type === 'direct'"
              >
              <input 
                v-model="proxy.port" 
                placeholder="端口"
                class="proxy-port"
                type="number"
                :disabled="proxy.type === 'direct'"
              >
            </div>
            
            <div class="form-row" v-if="proxy.type !== 'direct'">
              <input 
                v-model="proxy.username" 
                placeholder="用户名 (可选)"
                class="proxy-input"
              >
              <input 
                v-model="proxy.password" 
                placeholder="密码 (可选)"
                type="password"
                class="proxy-input"
              >
            </div>
            
            <div class="form-row">
              <button @click="setProxy" class="btn btn-primary">设置代理</button>
              <button @click="clearProxy" class="btn btn-secondary">清除代理</button>
              <button @click="testProxy" class="btn btn-success" :disabled="proxyTest.testing">
                {{ proxyTest.testing ? '测试中...' : '测试代理' }}
              </button>
            </div>
          </div>
        </div>

        <div class="proxy-status">
          <h4>代理状态：</h4>
          <div class="proxy-info">
            <p>当前代理: {{ currentProxy.type === 'direct' ? '直接连接' : `${currentProxy.type}://${currentProxy.host}:${currentProxy.port}` }}</p>
            <p>状态: {{ currentProxy.status }}</p>
            <p v-if="proxyTestResult.tested">
              测试结果: {{ proxyTestResult.success ? '✅ 连接成功' : '❌ 连接失败' }}
              {{ proxyTestResult.responseTime ? `(${proxyTestResult.responseTime}ms)` : '' }}
            </p>
          </div>
        </div>
      </div>

      <!-- 6. Cookie 管理 -->
      <div class="demo-section">
        <h3>🍪 Cookie 管理</h3>
        <p class="description">查看和管理网站Cookie</p>
        <div class="controls">
          <div class="cookie-form">
            <div class="form-row">
              <input 
                v-model="cookie.domain" 
                placeholder="域名 (如: .github.com)"
                class="cookie-input"
              >
              <button @click="getCookies" class="btn btn-primary">获取Cookie</button>
              <button @click="clearDomainCookies" class="btn btn-danger">清除域名Cookie</button>
            </div>
            
            <div class="form-row">
              <input 
                v-model="cookie.name" 
                placeholder="Cookie名称"
                class="cookie-input"
              >
              <input 
                v-model="cookie.value" 
                placeholder="Cookie值"
                class="cookie-input"
              >
              <button @click="setCookie" class="btn btn-success">设置Cookie</button>
            </div>
          </div>
        </div>

        <div class="cookie-list">
          <h4>Cookie 列表：</h4>
          <div v-if="cookies.length === 0" class="empty-state">
            暂无Cookie数据
          </div>
          <div v-else class="cookies-table">
            <div class="table-header">
              <span class="col-name">名称</span>
              <span class="col-value">值</span>
              <span class="col-domain">域名</span>
              <span class="col-expires">过期时间</span>
              <span class="col-actions">操作</span>
            </div>
            <div v-for="(cookieItem, index) in cookies" :key="index" class="table-row">
              <span class="col-name">{{ cookieItem.name }}</span>
              <span class="col-value" :title="cookieItem.value">{{ truncateText(cookieItem.value, 30) }}</span>
              <span class="col-domain">{{ cookieItem.domain }}</span>
              <span class="col-expires">{{ formatExpires(cookieItem.expirationDate) }}</span>
              <span class="col-actions">
                <button @click="deleteCookie(cookieItem)" class="btn btn-danger btn-sm">删除</button>
              </span>
            </div>
          </div>
          
          <div class="cookie-actions" v-if="cookies.length > 0">
            <button @click="exportCookies" class="btn btn-success btn-sm">导出Cookie</button>
            <button @click="clearAllCookies" class="btn btn-danger btn-sm">清空全部</button>
          </div>
        </div>
      </div>

    </div>

    <!-- 消息提示 -->
    <div v-if="message.text" :class="['message', message.type]">
      {{ message.text }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'

// HTTP请求相关
const httpRequest = reactive({
  method: 'GET',
  url: 'https://api.github.com/users/github',
  headers: '{}',
  body: '{}',
  loading: false
})

const httpHistory = ref<any[]>([])

// WebSocket相关
const websocket = reactive({
  url: 'wss://echo.websocket.org/',
  connected: false,
  connecting: false,
  message: '',
  connectionTime: 0
})

const websocketMessages = ref<any[]>([])
const messagesContainer = ref<HTMLElement>()
let ws: WebSocket | null = null
let wsTimer: number | null = null

// 下载相关
const download = reactive({
  url: '',
  filename: '',
  downloading: false
})

const downloadTasks = ref<any[]>([])

// 网络状态相关
const networkStatus = reactive({
  online: navigator.onLine,
  connectionType: '',
  downloadSpeed: '',
  latency: '',
  lastUpdate: ''
})

const networkTest = reactive({
  running: false
})

const networkChart = reactive({
  data: [] as any[]
})

const networkCanvas = ref<HTMLCanvasElement>()
const pingResults = ref<any[]>([])

// 代理相关
const proxy = reactive({
  type: 'direct',
  host: '',
  port: '',
  username: '',
  password: ''
})

const currentProxy = reactive({
  type: 'direct',
  host: '',
  port: '',
  status: '未设置'
})

const proxyTest = reactive({
  testing: false
})

const proxyTestResult = reactive({
  tested: false,
  success: false,
  responseTime: 0
})

// Cookie相关
const cookie = reactive({
  domain: '',
  name: '',
  value: ''
})

const cookies = ref<any[]>([])

// 消息提示
const message = reactive({
  text: '',
  type: 'info'
})

/**
 * 发送HTTP请求
 */
const sendHttpRequest = async () => {
  if (!httpRequest.url.trim()) {
    showMessage('请输入请求URL', 'warning')
    return
  }

  httpRequest.loading = true
  const startTime = Date.now()

  try {
    let headers = {}
    try {
      headers = JSON.parse(httpRequest.headers || '{}')
    } catch (e) {
      console.warn('请求头格式错误，使用默认值')
    }

    let body = undefined
    if (httpRequest.method !== 'GET' && httpRequest.body.trim()) {
      try {
        body = JSON.parse(httpRequest.body)
      } catch (e) {
        body = httpRequest.body
      }
    }

    const response = await fetch(httpRequest.url, {
      method: httpRequest.method,
      headers: headers as any,
      body: body ? JSON.stringify(body) : undefined
    })

    const responseTime = Date.now() - startTime
    const responseText = await response.text()
    let responseData
    
    try {
      responseData = JSON.parse(responseText)
    } catch (e) {
      responseData = responseText
    }

    const historyItem = {
      method: httpRequest.method,
      url: httpRequest.url,
      status: response.status,
      statusText: response.statusText,
      responseTime,
      contentLength: responseText.length,
      response: responseData,
      responseHeaders: Object.fromEntries(response.headers.entries()),
      timestamp: new Date().toLocaleString(),
      expanded: false
    }

    httpHistory.value.unshift(historyItem)
    
    // 限制历史记录数量
    if (httpHistory.value.length > 20) {
      httpHistory.value = httpHistory.value.slice(0, 20)
    }

    showMessage(`请求成功 - ${response.status} (${responseTime}ms)`, 'success')
  } catch (error) {
    const responseTime = Date.now() - startTime
    const historyItem = {
      method: httpRequest.method,
      url: httpRequest.url,
      status: 0,
      statusText: 'Network Error',
      responseTime,
      contentLength: 0,
      response: error.toString(),
      responseHeaders: {},
      timestamp: new Date().toLocaleString(),
      expanded: false
    }

    httpHistory.value.unshift(historyItem)
    showMessage('请求失败: ' + error, 'error')
  } finally {
    httpRequest.loading = false
  }
}

/**
 * 切换请求详情显示
 */
const toggleRequestDetails = (index: number) => {
  httpHistory.value[index].expanded = !httpHistory.value[index].expanded
}

/**
 * 获取状态码样式类
 */
const getStatusClass = (status: number): string => {
  if (status >= 200 && status < 300) return 'success'
  if (status >= 300 && status < 400) return 'info'
  if (status >= 400 && status < 500) return 'warning'
  if (status >= 500) return 'error'
  return 'default'
}

/**
 * 格式化响应内容
 */
const formatResponse = (response: any): string => {
  if (typeof response === 'object') {
    return JSON.stringify(response, null, 2)
  }
  return response
}

/**
 * 连接WebSocket
 */
const connectWebSocket = () => {
  if (!websocket.url.trim()) {
    showMessage('请输入WebSocket URL', 'warning')
    return
  }

  websocket.connecting = true

  try {
    ws = new WebSocket(websocket.url)

    ws.onopen = () => {
      websocket.connected = true
      websocket.connecting = false
      websocket.connectionTime = 0
      
      wsTimer = setInterval(() => {
        websocket.connectionTime++
      }, 1000)

      addWebSocketMessage('系统', '连接已建立', 'system')
      showMessage('WebSocket连接成功', 'success')
    }

    ws.onmessage = (event) => {
      addWebSocketMessage('received', event.data, 'received')
    }

    ws.onclose = () => {
      websocket.connected = false
      websocket.connecting = false
      
      if (wsTimer) {
        clearInterval(wsTimer)
        wsTimer = null
      }

      addWebSocketMessage('系统', '连接已断开', 'system')
      showMessage('WebSocket连接已断开', 'info')
    }

    ws.onerror = (error) => {
      websocket.connecting = false
      addWebSocketMessage('系统', '连接错误', 'error')
      showMessage('WebSocket连接错误', 'error')
    }
  } catch (error) {
    websocket.connecting = false
    showMessage('WebSocket连接失败: ' + error, 'error')
  }
}

/**
 * 断开WebSocket连接
 */
const disconnectWebSocket = () => {
  if (ws) {
    ws.close()
    ws = null
  }
}

/**
 * 发送WebSocket消息
 */
const sendWebSocketMessage = () => {
  if (!websocket.message.trim()) return

  if (ws && ws.readyState === WebSocket.OPEN) {
    ws.send(websocket.message)
    addWebSocketMessage('sent', websocket.message, 'sent')
    websocket.message = ''
  } else {
    showMessage('WebSocket未连接', 'warning')
  }
}

/**
 * 添加WebSocket消息
 */
const addWebSocketMessage = (type: string, content: string, messageType: string) => {
  websocketMessages.value.push({
    type: messageType,
    content,
    timestamp: new Date().toLocaleTimeString()
  })

  // 限制消息数量
  if (websocketMessages.value.length > 100) {
    websocketMessages.value = websocketMessages.value.slice(-100)
  }

  // 滚动到底部
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
    }
  })
}

/**
 * 清空WebSocket消息
 */
const clearWebSocketMessages = () => {
  websocketMessages.value = []
  showMessage('消息记录已清空', 'info')
}

/**
 * 导出消息
 */
const exportMessages = () => {
  const messages = websocketMessages.value.map(msg => 
    `[${msg.timestamp}] ${msg.type === 'sent' ? '发送' : '接收'}: ${msg.content}`
  ).join('\n')

  const blob = new Blob([messages], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `websocket-messages-${Date.now()}.txt`
  a.click()
  URL.revokeObjectURL(url)

  showMessage('消息已导出', 'success')
}

/**
 * 开始下载
 */
const startDownload = async () => {
  if (!download.url.trim()) {
    showMessage('请输入下载URL', 'warning')
    return
  }

  const filename = download.filename || download.url.split('/').pop() || `download-${Date.now()}`
  
  const task = {
    url: download.url,
    filename,
    progress: 0,
    receivedBytes: 0,
    totalBytes: 0,
    speed: '0 KB/s',
    timeRemaining: '计算中...',
    status: 'downloading',
    startTime: Date.now()
  }

  downloadTasks.value.push(task)
  download.downloading = true

  try {
    // 模拟下载进度
    const simulateDownload = () => {
      const taskIndex = downloadTasks.value.length - 1
      const currentTask = downloadTasks.value[taskIndex]
      
      if (currentTask.status !== 'downloading') return

      const increment = Math.random() * 10 + 5
      currentTask.progress = Math.min(currentTask.progress + increment, 100)
      currentTask.receivedBytes = Math.floor((currentTask.progress / 100) * 10000000) // 假设10MB文件
      currentTask.totalBytes = 10000000

      const elapsedTime = (Date.now() - currentTask.startTime) / 1000
      const speed = currentTask.receivedBytes / elapsedTime
      currentTask.speed = formatFileSize(speed) + '/s'

      if (currentTask.progress < 100) {
        const remainingBytes = currentTask.totalBytes - currentTask.receivedBytes
        const timeRemaining = remainingBytes / speed
        currentTask.timeRemaining = formatTime(Math.floor(timeRemaining))
        
        setTimeout(simulateDownload, 500 + Math.random() * 1000)
      } else {
        currentTask.status = 'completed'
        currentTask.timeRemaining = '已完成'
        download.downloading = false
        showMessage(`文件下载完成: ${filename}`, 'success')
      }
    }

    simulateDownload()
  } catch (error) {
    download.downloading = false
    showMessage('下载失败: ' + error, 'error')
  }
}

/**
 * 暂停下载
 */
const pauseDownload = (index: number) => {
  downloadTasks.value[index].status = 'paused'
  showMessage('下载已暂停', 'info')
}

/**
 * 继续下载
 */
const resumeDownload = (index: number) => {
  downloadTasks.value[index].status = 'downloading'
  showMessage('下载已继续', 'info')
}

/**
 * 取消下载
 */
const cancelDownload = (index: number) => {
  downloadTasks.value[index].status = 'cancelled'
  showMessage('下载已取消', 'info')
}

/**
 * 刷新网络状态
 */
const refreshNetworkStatus = () => {
  networkStatus.online = navigator.onLine
  networkStatus.lastUpdate = new Date().toLocaleString()
  
  // 获取连接信息 (如果支持)
  if ('connection' in navigator) {
    const connection = (navigator as any).connection
    networkStatus.connectionType = connection?.effectiveType || '未知'
  }

  showMessage('网络状态已刷新', 'info')
}

/**
 * 运行网络测试
 */
const runNetworkTest = async () => {
  networkTest.running = true

  try {
    // 测试下载速度
    const startTime = Date.now()
    const response = await fetch('https://httpbin.org/bytes/1024', { cache: 'no-cache' })
    const blob = await response.blob()
    const endTime = Date.now()
    
    const duration = (endTime - startTime) / 1000
    const speed = (blob.size / duration) / 1024 // KB/s
    networkStatus.downloadSpeed = `${speed.toFixed(2)} KB/s`

    // 测试延迟
    const pingStart = Date.now()
    await fetch('https://httpbin.org/get', { cache: 'no-cache' })
    const pingEnd = Date.now()
    networkStatus.latency = `${pingEnd - pingStart}ms`

    // 添加到图表数据
    networkChart.data.push({
      time: new Date().toLocaleTimeString(),
      speed: speed,
      latency: pingEnd - pingStart
    })

    // 限制数据点数量
    if (networkChart.data.length > 20) {
      networkChart.data = networkChart.data.slice(-20)
    }

    showMessage('网络测试完成', 'success')
  } catch (error) {
    showMessage('网络测试失败: ' + error, 'error')
  } finally {
    networkTest.running = false
  }
}

/**
 * Ping测试
 */
const pingTest = async () => {
  const hosts = ['github.com', 'google.com', 'baidu.com']
  
  for (const host of hosts) {
    try {
      const startTime = Date.now()
      // 使用fetch模拟ping (实际应该使用专门的ping API)
      await fetch(`https://${host}`, { mode: 'no-cors', cache: 'no-cache' })
      const endTime = Date.now()
      
      pingResults.value.unshift({
        host,
        success: true,
        time: endTime - startTime,
        timestamp: new Date().toLocaleTimeString()
      })
    } catch (error) {
      pingResults.value.unshift({
        host,
        success: false,
        time: 0,
        timestamp: new Date().toLocaleTimeString()
      })
    }
  }

  // 限制结果数量
  if (pingResults.value.length > 50) {
    pingResults.value = pingResults.value.slice(0, 50)
  }

  showMessage('Ping测试完成', 'info')
}

/**
 * 设置代理
 */
const setProxy = async () => {
  try {
    // 这里应该调用Electron的API来设置代理
    // await window.api.network.setProxy(proxy)
    
    currentProxy.type = proxy.type
    currentProxy.host = proxy.host
    currentProxy.port = proxy.port
    currentProxy.status = '已设置'

    showMessage('代理设置成功', 'success')
  } catch (error) {
    showMessage('代理设置失败: ' + error, 'error')
  }
}

/**
 * 清除代理
 */
const clearProxy = async () => {
  try {
    // await window.api.network.clearProxy()
    
    currentProxy.type = 'direct'
    currentProxy.host = ''
    currentProxy.port = ''
    currentProxy.status = '直接连接'

    showMessage('代理已清除', 'info')
  } catch (error) {
    showMessage('清除代理失败: ' + error, 'error')
  }
}

/**
 * 测试代理
 */
const testProxy = async () => {
  proxyTest.testing = true

  try {
    const startTime = Date.now()
    // 这里应该通过代理发送测试请求
    await fetch('https://httpbin.org/ip', { cache: 'no-cache' })
    const endTime = Date.now()

    proxyTestResult.tested = true
    proxyTestResult.success = true
    proxyTestResult.responseTime = endTime - startTime

    showMessage('代理测试成功', 'success')
  } catch (error) {
    proxyTestResult.tested = true
    proxyTestResult.success = false
    proxyTestResult.responseTime = 0

    showMessage('代理测试失败: ' + error, 'error')
  } finally {
    proxyTest.testing = false
  }
}

/**
 * 获取Cookie
 */
const getCookies = async () => {
  if (!cookie.domain.trim()) {
    showMessage('请输入域名', 'warning')
    return
  }

  try {
    // 这里应该调用Electron的API来获取Cookie
    // const result = await window.api.network.getCookies(cookie.domain)
    
    // 模拟Cookie数据
    const mockCookies = [
      {
        name: 'session_id',
        value: 'abc123def456',
        domain: cookie.domain,
        expirationDate: Date.now() + 86400000
      },
      {
        name: 'user_pref',
        value: 'theme=dark;lang=zh',
        domain: cookie.domain,
        expirationDate: Date.now() + 86400000 * 30
      }
    ]

    cookies.value = mockCookies
    showMessage(`获取到 ${mockCookies.length} 个Cookie`, 'success')
  } catch (error) {
    showMessage('获取Cookie失败: ' + error, 'error')
  }
}

/**
 * 设置Cookie
 */
const setCookie = async () => {
  if (!cookie.name.trim() || !cookie.value.trim()) {
    showMessage('请输入Cookie名称和值', 'warning')
    return
  }

  try {
    // await window.api.network.setCookie({
    //   name: cookie.name,
    //   value: cookie.value,
    //   domain: cookie.domain || window.location.hostname
    // })

    showMessage('Cookie设置成功', 'success')
    
    // 重新获取Cookie列表
    if (cookie.domain) {
      getCookies()
    }
  } catch (error) {
    showMessage('设置Cookie失败: ' + error, 'error')
  }
}

/**
 * 删除Cookie
 */
const deleteCookie = async (cookieItem: any) => {
  try {
    // await window.api.network.deleteCookie(cookieItem)
    
    cookies.value = cookies.value.filter(c => c.name !== cookieItem.name)
    showMessage('Cookie已删除', 'info')
  } catch (error) {
    showMessage('删除Cookie失败: ' + error, 'error')
  }
}

/**
 * 清除域名Cookie
 */
const clearDomainCookies = async () => {
  if (!cookie.domain.trim()) {
    showMessage('请输入域名', 'warning')
    return
  }

  try {
    // await window.api.network.clearDomainCookies(cookie.domain)
    
    cookies.value = []
    showMessage('域名Cookie已清除', 'info')
  } catch (error) {
    showMessage('清除Cookie失败: ' + error, 'error')
  }
}

/**
 * 清空所有Cookie
 */
const clearAllCookies = async () => {
  try {
    // await window.api.network.clearAllCookies()
    
    cookies.value = []
    showMessage('所有Cookie已清除', 'info')
  } catch (error) {
    showMessage('清除所有Cookie失败: ' + error, 'error')
  }
}

/**
 * 导出Cookie
 */
const exportCookies = () => {
  const cookieData = cookies.value.map(c => ({
    name: c.name,
    value: c.value,
    domain: c.domain,
    expires: new Date(c.expirationDate).toISOString()
  }))

  const blob = new Blob([JSON.stringify(cookieData, null, 2)], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `cookies-${Date.now()}.json`
  a.click()
  URL.revokeObjectURL(url)

  showMessage('Cookie已导出', 'success')
}

/**
 * 格式化过期时间
 */
const formatExpires = (timestamp: number): string => {
  return new Date(timestamp).toLocaleString()
}

/**
 * 截断文本
 */
const truncateText = (text: string, maxLength: number): string => {
  if (text.length <= maxLength) return text
  return text.substring(0, maxLength) + '...'
}

/**
 * 格式化时间
 */
const formatTime = (seconds: number): string => {
  if (seconds < 60) return `${seconds}秒`
  const minutes = Math.floor(seconds / 60)
  const remainingSeconds = seconds % 60
  return `${minutes}分${remainingSeconds}秒`
}

/**
 * 格式化文件大小
 */
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 显示消息提示
 */
const showMessage = (text: string, type: 'success' | 'error' | 'warning' | 'info' = 'info') => {
  message.text = text
  message.type = type
  
  setTimeout(() => {
    message.text = ''
  }, 3000)
}

// 网络状态监听
const handleOnline = () => {
  networkStatus.online = true
  showMessage('网络已连接', 'success')
}

const handleOffline = () => {
  networkStatus.online = false
  showMessage('网络已断开', 'warning')
}

// 生命周期
onMounted(() => {
  showMessage('网络功能演示已就绪', 'success')
  
  // 监听网络状态变化
  window.addEventListener('online', handleOnline)
  window.addEventListener('offline', handleOffline)
  
  // 初始化网络状态
  refreshNetworkStatus()
})

onUnmounted(() => {
  // 清理资源
  if (ws) {
    ws.close()
    ws = null
  }
  
  if (wsTimer) {
    clearInterval(wsTimer)
    wsTimer = null
  }
  
  // 移除事件监听
  window.removeEventListener('online', handleOnline)
  window.removeEventListener('offline', handleOffline)
  
  console.log('网络功能演示组件已卸载')
})
</script>

<style scoped>
.network-features-page {
  min-height: 100vh;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  box-sizing: border-box;
}

.header {
  text-align: center;
  margin-bottom: 40px;
}

.header h2 {
  color: var(--text-primary, #2c3e50);
  margin: 0;
  font-size: 2.2em;
}

.subtitle {
  color: var(--text-secondary, #7f8c8d);
  margin: 5px 0 0 0;
  font-size: 1.1em;
}

.demo-sections {
  display: grid;
  gap: 30px;
}

.demo-section {
  background: var(--card-bg, #f8f9fa);
  border-radius: 12px;
  padding: 25px;
  border-left: 4px solid var(--primary-color, #3498db);
  box-shadow: var(--shadow-sm, 0 2px 10px rgba(0, 0, 0, 0.1));
  border: 1px solid var(--card-border, transparent);
}

.demo-section h3 {
  margin: 0 0 10px 0;
  color: var(--text-primary, #2c3e50);
  font-size: 1.3em;
}

.description {
  color: var(--text-secondary, #666);
  margin: 0 0 20px 0;
  font-size: 14px;
  line-height: 1.5;
}

.controls {
  margin-bottom: 20px;
}

.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
  min-width: 100px;
}

.btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: var(--shadow, 0 4px 8px rgba(0, 0, 0, 0.2));
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.btn-primary {
  background: linear-gradient(45deg, var(--primary-color, #3498db), var(--primary-hover, #2980b9));
  color: var(--text-inverse, white);
}

.btn-secondary {
  background: linear-gradient(45deg, var(--text-secondary, #95a5a6), #7f8c8d);
  color: var(--text-inverse, white);
}

.btn-success {
  background: linear-gradient(45deg, var(--success-color, #2ecc71), var(--success-hover, #27ae60));
  color: var(--text-inverse, white);
}

.btn-danger {
  background: linear-gradient(45deg, var(--error-color, #e74c3c), var(--error-hover, #c0392b));
  color: var(--text-inverse, white);
}

.btn-warning {
  background: linear-gradient(45deg, var(--warning-color, #f39c12), var(--warning-hover, #e67e22));
  color: var(--text-inverse, white);
}

.btn-sm {
  padding: 5px 10px;
  font-size: 12px;
  min-width: 60px;
}

/* HTTP请求表单 */
.request-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.form-row {
  display: flex;
  gap: 15px;
  align-items: center;
  flex-wrap: wrap;
}

.method-select {
  padding: 10px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
  min-width: 100px;
}

.url-input {
  flex: 1;
  min-width: 300px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.headers-input, .body-input {
  width: 100%;
  min-height: 80px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  resize: vertical;
}

.url-input:focus, .headers-input:focus, .body-input:focus, .method-select:focus {
  outline: none;
  border-color: var(--primary-color, #3498db);
  box-shadow: var(--input-focus-shadow, 0 0 0 0.2rem rgba(52, 152, 219, 0.25));
}

/* 请求历史 */
.request-history {
  margin-top: 30px;
}

.request-history h4 {
  color: var(--text-primary, #333);
  margin: 0 0 15px 0;
}

.empty-state {
  color: var(--text-muted, #999);
  font-style: italic;
  text-align: center;
  padding: 20px;
  background: var(--bg-tertiary, #f5f5f5);
  border-radius: 6px;
}

.history-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.history-item {
  background: var(--bg-secondary, white);
  border-radius: 8px;
  padding: 15px;
  border: 1px solid var(--border-color, #ddd);
}

.request-header {
  display: flex;
  align-items: center;
  gap: 15px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.method-badge {
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: bold;
  color: var(--text-inverse, white);
  min-width: 60px;
  text-align: center;
}

.method-badge.get { background: var(--success-color, #2ecc71); }
.method-badge.post { background: var(--primary-color, #3498db); }
.method-badge.put { background: var(--warning-color, #f39c12); }
.method-badge.delete { background: var(--error-color, #e74c3c); }
.method-badge.patch { background: var(--info-color, #9b59b6); }

.url {
  flex: 1;
  color: var(--text-primary, #333);
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
  word-break: break-all;
}

.status-badge {
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: bold;
  color: var(--text-inverse, white);
  min-width: 60px;
  text-align: center;
}

.status-badge.success { background: var(--success-color, #2ecc71); }
.status-badge.info { background: var(--info-color, #3498db); }
.status-badge.warning { background: var(--warning-color, #f39c12); }
.status-badge.error { background: var(--error-color, #e74c3c); }
.status-badge.default { background: var(--text-secondary, #95a5a6); }

.timestamp {
  color: var(--text-muted, #666);
  font-size: 12px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

.request-details {
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid var(--border-color, #eee);
}

.response-info, .response-headers, .response-body {
  margin-bottom: 15px;
}

.response-info h5, .response-headers h5, .response-body h5 {
  color: var(--text-primary, #333);
  margin: 0 0 10px 0;
  font-size: 14px;
}

.response-info p {
  margin: 5px 0;
  color: var(--text-secondary, #666);
  font-size: 13px;
}

.headers-display, .response-display {
  background: var(--bg-tertiary, #f8f9fa);
  border: 1px solid var(--border-color, #e9ecef);
  border-radius: 4px;
  padding: 10px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 12px;
  color: var(--text-primary, #333);
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 200px;
  overflow-y: auto;
}

/* WebSocket相关 */
.websocket-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.ws-url-input {
  flex: 1;
  min-width: 300px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.websocket-status {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 10px 15px;
  background: var(--bg-tertiary, #f5f5f5);
  border-radius: 6px;
}

.status-indicator {
  font-weight: bold;
  padding: 5px 10px;
  border-radius: 4px;
}

.status-indicator.connected {
  background: var(--success-light, #d4edda);
  color: var(--success-color, #155724);
}

.status-indicator.disconnected {
  background: var(--error-light, #f8d7da);
  color: var(--error-color, #721c24);
}

.connection-info {
  color: var(--text-secondary, #666);
  font-size: 13px;
}

.message-input {
  flex: 1;
  min-width: 250px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.websocket-messages {
  margin-top: 20px;
}

.websocket-messages h4 {
  color: var(--text-primary, #333);
  margin: 0 0 15px 0;
}

.messages-container {
  max-height: 300px;
  overflow-y: auto;
  background: var(--bg-secondary, #f9f9f9);
  border-radius: 6px;
  padding: 15px;
  border: 1px solid var(--border-color, #ddd);
}

.message-item {
  margin-bottom: 15px;
  padding: 10px;
  border-radius: 6px;
}

.message-item.sent {
  background: var(--primary-light, #e3f2fd);
  border-left: 4px solid var(--primary-color, #3498db);
}

.message-item.received {
  background: var(--success-light, #e8f5e8);
  border-left: 4px solid var(--success-color, #2ecc71);
}

.message-item.system {
  background: var(--warning-light, #fff4e6);
  border-left: 4px solid var(--warning-color, #f39c12);
}

.message-item.error {
  background: var(--error-light, #ffe6e6);
  border-left: 4px solid var(--error-color, #e74c3c);
}

.message-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 5px;
}

.message-type {
  font-weight: bold;
  font-size: 12px;
  color: var(--text-primary, #333);
}

.message-timestamp {
  font-size: 11px;
  color: var(--text-muted, #666);
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

.message-content {
  color: var(--text-primary, #333);
  font-size: 14px;
  word-wrap: break-word;
}

.messages-actions {
  margin-top: 10px;
  display: flex;
  gap: 10px;
  justify-content: center;
}

/* 下载管理 */
.download-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.download-url-input {
  flex: 2;
  min-width: 300px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.filename-input {
  flex: 1;
  min-width: 150px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.download-list {
  margin-top: 20px;
}

.download-list h4 {
  color: var(--text-primary, #333);
  margin: 0 0 15px 0;
}

.download-item {
  background: var(--bg-secondary, white);
  border-radius: 8px;
  padding: 15px;
  margin-bottom: 15px;
  border: 1px solid var(--border-color, #ddd);
}

.download-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.filename {
  font-weight: bold;
  color: var(--text-primary, #333);
}

.download-stats {
  display: flex;
  gap: 15px;
  color: var(--text-secondary, #666);
  font-size: 13px;
}

.download-progress {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 10px;
}

.progress-bar {
  flex: 1;
  height: 8px;
  background: var(--bg-tertiary, #f0f0f0);
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(45deg, var(--success-color, #2ecc71), var(--primary-color, #3498db));
  border-radius: 4px;
  transition: width 0.3s ease;
}

.progress-text {
  font-weight: bold;
  color: var(--text-primary, #333);
  font-size: 13px;
  min-width: 40px;
}

.download-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}

/* 网络状态面板 */
.network-status-panel {
  margin-top: 20px;
}

.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.status-card {
  background: var(--bg-secondary, white);
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  border: 1px solid var(--border-color, #ddd);
}

.status-card h5 {
  color: var(--text-primary, #333);
  margin: 0 0 10px 0;
  font-size: 14px;
}

.status-value {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 5px;
}

.status-value.online { color: var(--success-color, #2ecc71); }
.status-value.offline { color: var(--error-color, #e74c3c); }

.status-description {
  color: var(--text-secondary, #666);
  font-size: 12px;
  margin: 0;
}

/* Ping结果 */
.ping-results {
  margin-top: 20px;
}

.ping-results h4 {
  color: var(--text-primary, #333);
  margin: 0 0 15px 0;
}

.ping-list {
  background: var(--bg-secondary, #f9f9f9);
  border-radius: 6px;
  padding: 15px;
  border: 1px solid var(--border-color, #ddd);
  max-height: 200px;
  overflow-y: auto;
}

.ping-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-color, #eee);
}

.ping-item:last-child {
  border-bottom: none;
}

.ping-host {
  font-weight: bold;
  color: var(--text-primary, #333);
}

.ping-time {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
}

.ping-time.success { color: var(--success-color, #2ecc71); }
.ping-time.failed { color: var(--error-color, #e74c3c); }

.ping-timestamp {
  color: var(--text-muted, #666);
  font-size: 11px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

/* 代理设置 */
.proxy-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.proxy-type-select {
  min-width: 120px;
  padding: 10px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.proxy-input {
  flex: 1;
  min-width: 150px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.proxy-port {
  width: 100px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.proxy-status {
  margin-top: 20px;
  background: var(--bg-tertiary, #f5f5f5);
  border-radius: 6px;
  padding: 15px;
}

.proxy-status h4 {
  color: var(--text-primary, #333);
  margin: 0 0 10px 0;
}

.proxy-info p {
  margin: 5px 0;
  color: var(--text-primary, #333);
}

/* Cookie管理 */
.cookie-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.cookie-input {
  flex: 1;
  min-width: 150px;
  padding: 10px 15px;
  border: 2px solid var(--border-color, #bdc3c7);
  border-radius: 6px;
  background: var(--input-bg, white);
  color: var(--text-primary, #333);
  font-size: 14px;
}

.cookie-list {
  margin-top: 20px;
}

.cookie-list h4 {
  color: var(--text-primary, #333);
  margin: 0 0 15px 0;
}

.cookies-table {
  background: var(--bg-secondary, white);
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--border-color, #ddd);
}

.table-header {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr 1fr auto;
  gap: 15px;
  padding: 15px;
  background: var(--bg-tertiary, #f5f5f5);
  font-weight: bold;
  color: var(--text-primary, #333);
  font-size: 13px;
  border-bottom: 1px solid var(--border-color, #ddd);
}

.table-row {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr 1fr auto;
  gap: 15px;
  padding: 10px 15px;
  border-bottom: 1px solid var(--border-color, #eee);
  align-items: center;
}

.table-row:last-child {
  border-bottom: none;
}

.col-name, .col-value, .col-domain, .col-expires {
  color: var(--text-primary, #333);
  font-size: 13px;
  word-wrap: break-word;
}

.col-value {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  color: var(--text-secondary, #666);
}

.cookie-actions {
  margin-top: 10px;
  display: flex;
  gap: 10px;
  justify-content: center;
}

/* 消息提示 */
.message {
  position: fixed;
  top: 20px;
  right: 20px;
  padding: 15px 20px;
  border-radius: 8px;
  color: var(--text-inverse, white);
  font-weight: 600;
  z-index: 1000;
  animation: slideIn 0.3s ease;
  max-width: 400px;
  box-shadow: var(--shadow, 0 4px 12px rgba(0, 0, 0, 0.15));
}

.message.success {
  background: var(--success-color, #28a745);
}

.message.error {
  background: var(--error-color, #dc3545);
}

.message.warning {
  background: var(--warning-color, #ffc107);
  color: var(--text-primary, #333);
}

.message.info {
  background: var(--info-color, #17a2b8);
}

@keyframes slideIn {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .network-features-page {
    padding: 15px;
  }
  
  .form-row {
    flex-direction: column;
    align-items: stretch;
  }
  
  .btn, .method-select, .url-input, .ws-url-input, .download-url-input, .filename-input, .proxy-input, .cookie-input {
    width: 100%;
  }
  
  .status-grid {
    grid-template-columns: 1fr;
  }
  
  .request-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .table-header, .table-row {
    grid-template-columns: 1fr;
    gap: 5px;
  }
  
  .table-header span, .table-row span {
    padding: 5px 0;
  }
}
</style>

